package com.mutual.reins.verify.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mutual.base.exception.BusinessException;
import com.mutual.reins.danger.entity.PrpReinsVerify;
import com.mutual.reins.danger.entity.PrppDangerUnit;
import com.mutual.reins.danger.service.*;
import com.mutual.reins.excessloss.entity.FeoxLayer;
import com.mutual.reins.excessloss.service.IFeoxLayerService;
import com.mutual.reins.excessloss.service.IFeoxPlanService;
import com.mutual.reins.excessloss.service.IFeoxReinsService;
import com.mutual.reins.interf.entity.*;
import com.mutual.reins.interf.service.*;
import com.mutual.reins.trial.service.IPrppReinsShareService;
import com.mutual.reins.trial.service.IPrppReinsTrialService;
import com.mutual.reins.utils.constraint.ReinsConst;
import com.mutual.reins.utils.constraint.UserExceptionEnum;
import com.mutual.reins.verify.service.IVerifyPrppDangerUnitService;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * @author zjl
 */
@Slf4j
public class VerifyPrppDangerUnitServiceImpl implements IVerifyPrppDangerUnitService {
    @Autowired
    private IPrppDangerUnitService iPrppDangerUnitService;
    @Autowired
    private IFeoEnquiryService iFeoEnquiryService;
    @Autowired
    private IPrpReinsVerifyService iPrpReinsVerifyService;
    @Autowired
    private IReinsEndorCededService iReinsEndorCededService;
    @Autowired
    private IReinsInterFlogService iReinsInterFlogService;
    @Autowired
    private IFeoEngageService iFeoEngageService;
    @Autowired
    private IFeoTotService iFeoTotService;
    @Autowired
    private IFeoCoinsService iFeoCoinsService;
    @Autowired
    private IFeoItemService iFeoItemService;
    @Autowired
    private IFeoReinsReceiveService iFeoReinsReceiveService;
    @Autowired
    private IFeoReinsVerifyService iFeoReinsVerifyService;
    @Autowired
    private IFeoxPlanService iFeoxPlanService;
    @Autowired
    private IFeoxReinsService iFeoxReinsService;
    @Autowired
    private IFeoxLayerService iFeoxLayerService;
    @Autowired
    private IPrppReinsShareService iPrppReinsShareService;
    @Autowired
    private IPrppReinsTrialService iPrppReinsTrialService;
    @Autowired
    private IPrppDangerCoinsService iPrppDangerCoinsService;
    @Autowired
    private IPrppDangerPlanService iPrppDangerPlanService;
    @Autowired
    private IPrppDangerTotService iPrppDangerTotService;
    @Autowired
    private IPrppDangerItemService iPrppDangerItemService;
    @Autowired
    private IPrpReinsNotionService iPrpReinsNotionService;
    @Autowired
    private IGeneratePrppApplyDangerUnitService iGeneratePrppApplyDangerUnitService;
    /**
     * 再保批单危险单位数据校验
     *
     * @param cerTiNo   批单号
     * @param cerTiType 校验类型批单（E）
     * @return 返回校验结果信息对象
     */
    @Override
    public ReinsCheckDto reinsCheckData(String cerTiNo, String cerTiType) {
        log.info("{}审核通过前数据校验调入时间：{}",cerTiNo,DateUtil.now());
        ReinsCheckDto reinsCheckDto = new ReinsCheckDto();
        try {
            // 初始化双核审核通过前对再保数据校验返回信息
            reinsCheckDto.setCerTiNo(cerTiNo);
            reinsCheckDto.setCerTiType(cerTiType);
            reinsCheckDto.setStatusType("Y");
            reinsCheckDto.setStatusDesc("再保处理成功");
            checkReinsData(cerTiNo,cerTiType);

        } catch (BusinessException e) {
            reinsCheckDto.setStatusType("N");
            reinsCheckDto.setStatusDesc(e.getMessage());
            e.printStackTrace();
        }
        log.info("{}审核通过前数据校验调出时间：{}",cerTiNo,DateUtil.now());
        return reinsCheckDto;
    }

    /**
     * 再保投保单危险单位数据校验
     *
     * @param reinsDeleteDto 下发修改对象
     * @return 核心提交核保调用再保接口返回信息对象
     */
    @Override
    public ReinsStatusDto deleteReinsData(ReinsDeleteDto reinsDeleteDto) {
        log.info("下发修改调入时间：{}", DateUtil.now());
        ReinsStatusDto reinsStatusDto = new ReinsStatusDto();
        ReinsInterFlog reinsInterFlog = new ReinsInterFlog();
        try {
            // 初始化返回状态
            reinsStatusDto.setCerTiNo(reinsDeleteDto.getCerTiNo());
            reinsStatusDto.setCerTiType(reinsDeleteDto.getCerTiType());
            reinsStatusDto.setStatus("Y");

            reinsInterFlog.setCerTiNo(reinsDeleteDto.getCerTiNo());
            reinsInterFlog.setCerTiType(reinsDeleteDto.getCerTiType());
            reinsInterFlog.setOperatorCode(reinsDeleteDto.getOperatorCode());
            reinsInterFlog.setOperatorName(reinsDeleteDto.getOperatorName());
            reinsInterFlog.setOperatorDate(LocalDate.parse(reinsDeleteDto.getOperatorDateStr(), DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            // 初始化日志表时，日志表处理状态默认为不通过状态
            reinsInterFlog.setRecordFlag("0");
            if (ReinsConst.CERTITYPE_PRPT.equals(reinsDeleteDto.getCerTiType())) {
                deleteEndorData(reinsDeleteDto,reinsInterFlog);
            } else {
                reinsStatusDto.setStatus("N");
            }
        } catch (Exception e) {
            reinsStatusDto.setStatus("N");
            e.printStackTrace();
        }
        log.info("下发修改调出时间：{}", DateUtil.now());
        return reinsStatusDto;
    }
    /**
     * 校验投保单数据
     * @param cerTiNo 业务号
     * @param cerTiType 业务类型
     */
    private void checkReinsData(String cerTiNo, String cerTiType) {
        if (ReinsConst.CERTITYPE_PRPP.equals(cerTiType)) {
            //自留额，占比数据检查
            checkReinsUnitData(cerTiNo);
            //TODO 试算服务完成后调整
            //保证险类、责任险类，自留+附加自留额上限检查
            //试算服务未做，暂时不进行校验
            ///checkReinsRetentionData(cerTiNo);
            //判断是否有临分分出
            checkReinsFeoData(cerTiNo);
            //临分分入确认状态检查
            checkReinsVerifyData(cerTiNo);
        } else {
            throw new BusinessException(UserExceptionEnum.REINS_CERTI_TYPE.getCode(), UserExceptionEnum.REINS_CERTI_TYPE.getMessage(), this.getClass().getName() + ".checkReinsData(" + cerTiNo + ")");
        }
    }
    /**
     * 投保单自留额，占比数据检查
     * @param cerTiNo 业务号
     */
    private void checkReinsUnitData(String cerTiNo) {
        Map<String, Object> columnMap = new HashMap<String, Object>(16) {{
            put("ENDORSENO", cerTiNo);
        }};
        List<PrppDangerUnit> prppDangerUnitList = iPrppDangerUnitService.listByMap(columnMap);
        if (ObjectUtil.isNotNull(prppDangerUnitList) && !prppDangerUnitList.isEmpty()) {
            for (PrppDangerUnit prppDangerUnit : prppDangerUnitList) {
                if (prppDangerUnit.getRetentionValue().compareTo(BigDecimal.ZERO)==0) {
                    throw new BusinessException(UserExceptionEnum.REINS_RISK_ASSESSMENT.getCode(),UserExceptionEnum.REINS_RISK_ASSESSMENT.getMessage(), this.getClass().getName() + ".checkReinsUnitData(" + cerTiNo + ")");
                } else if (prppDangerUnit.getDangerShare().compareTo(ReinsConst.INIT_RATE)!=0) {
                    throw new BusinessException(UserExceptionEnum.REINS_DANGER_SHARE.getCode(), UserExceptionEnum.REINS_DANGER_SHARE.getMessage(), this.getClass().getName() + ".checkReinsUnitData(" + cerTiNo + ")");
                }
            }
        }

    }
    /**
     * 判断是否有临分分出
     * @param cerTiNo 业务号
     */
    private void checkReinsFeoData(String cerTiNo){
        QueryWrapper<FeoEnquiry> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("ENDORSENO",cerTiNo);
        queryWrapper.eq("ENQUIRYTYPE","E");
        List<FeoEnquiry> feoEnquiryList = iFeoEnquiryService.list(queryWrapper);
        if(ObjectUtil.isNotNull(feoEnquiryList) && feoEnquiryList.size()>0){
            for (FeoEnquiry feoEnquiry : feoEnquiryList) {
                if (!ReinsConst.ENQUIRY_FLAG_3.equals(feoEnquiry.getVerifyFlag()) && !ReinsConst.ENQUIRY_FLAG_9.equals(feoEnquiry.getVerifyFlag())) {
                    throw new BusinessException(UserExceptionEnum.REINS_FEOENQUIRY_OUT_CONFRIM.getCode(), UserExceptionEnum.REINS_FEOENQUIRY_OUT_CONFRIM.getMessage(), this.getClass().getName()+ ".checkReinsFeoData(" + cerTiNo + ")");
                }
            }
        }
    }
    /**
     * 临分分入确认状态检查
     * @param cerTiNo 业务号
     */
    private void checkReinsVerifyData(String cerTiNo) {
        PrpReinsVerify prpReinsVerify = iPrpReinsVerifyService.findByCerTiNo(cerTiNo);
        ReinsEndorCeded reinsEndorCeded = iReinsEndorCededService.getById(cerTiNo);
        if(ObjectUtil.isNotNull(reinsEndorCeded) ){
            if(ObjectUtil.isNull(prpReinsVerify)){
                throw new BusinessException(UserExceptionEnum.REINS_REINS_CONFRIM.getCode(), UserExceptionEnum.REINS_REINS_CONFRIM.getMessage(),
                        this.getClass().getName() + ".checkReinsVerifyData(" + cerTiNo + ")");
            }else {
                if(! ReinsConst.REINSVERFIFY_FALG_1.equals(prpReinsVerify.getReinsState())){
                    throw new BusinessException(UserExceptionEnum.REINS_FEOENQUIRY_IN_CONFRIM.getCode(), UserExceptionEnum.REINS_FEOENQUIRY_IN_CONFRIM.getMessage(),
                            this.getClass().getName() + ".checkReinsVerifyData(" + cerTiNo + ")");
                }
            }
        }
    }

    /**
     * 修改日志，删除再保系统数据
     * @param reinsDeleteDto 下发修改对象
     * @param reinsInterFlog 再保日志对象
     */
    private void deleteEndorData(ReinsDeleteDto reinsDeleteDto, ReinsInterFlog reinsInterFlog) {
        // 生成日志表
        try {
            // 查询序号
            Integer amxSerialNo = iReinsInterFlogService.selectMaxSerialNo(reinsDeleteDto.getCerTiNo());
            reinsInterFlog.setSerialNo(amxSerialNo+1);
            // 插入记录
            iReinsInterFlogService.save(reinsInterFlog);
        } catch (BusinessException exception) {
            log.error("投保单号：{}日志表生成错误" , reinsDeleteDto.getCerTiNo() );
            throw new BusinessException(UserExceptionEnum.REINS_INTERF_VERIFY_MESSAGE.getCode(),
                    UserExceptionEnum.REINS_INTERF_VERIFY_MESSAGE.getMessage());
        }
        // 删除再保数据
        try {
            log.info(">>>>>>>>>>批单号：{} 下发修改 begin >>>>>>>>>>>" , reinsDeleteDto.getCerTiNo());
            deleteReinsEndorData(reinsDeleteDto);
            log.info(">>>>>>>>>>批单号：{} 下发修改 end >>>>>>>>>>>" , reinsDeleteDto.getCerTiNo());
        } catch (Exception e) {
            log.error("批单号：{}下发修改错误" , reinsDeleteDto.getCerTiNo());
            throw e;
        }
        try {
            log.info(">>>>>>>>>>批单号：{}更新日志表 begin >>>>>>>>>>>" , reinsDeleteDto.getCerTiNo());
            // 判断是否是见费出单的下发修改
            if (ReinsConst.FLAG_ZERO.equals(reinsDeleteDto.getType())) {
                reinsInterFlog.setRecordFlag("2");
            } else if (ReinsConst.FLAG_ONE.equals(reinsDeleteDto.getType())) {
                reinsInterFlog.setRecordFlag("4");
            }
            iReinsInterFlogService.updateById(reinsInterFlog);
            log.info(">>>>>>>>>>批单号：{}更新日志表 end >>>>>>>>>>>" , reinsDeleteDto.getCerTiNo());
        } catch (Exception e) {
            log.error("批单号：{}日志表生成错误" , reinsDeleteDto.getCerTiNo() );
            throw e;
        }
    }
    /**
     * 删除再保系统数据
     * @param reinsDeleteDto 下发修改对象
     */
    private void deleteReinsEndorData(ReinsDeleteDto reinsDeleteDto) {
        Map<String, Object> columnMap = new HashMap<String, Object>(16) {{
            put("ENDORSENO", reinsDeleteDto.getCerTiNo());
        }};
        // 删除临分询价表
        log.info(">>>>>>>>下发修改：{}删除询价单信息开始>>>>>>>>>" , reinsDeleteDto.getCerTiNo());
        iFeoEngageService.removeByMap(columnMap);
        iFeoTotService.removeByMap(columnMap);
        iFeoCoinsService.removeByMap(columnMap);
        iFeoItemService.removeByMap(columnMap);
        iFeoReinsReceiveService.removeByMap(columnMap);
        iFeoReinsVerifyService.removeByMap(columnMap);
        iFeoEnquiryService.removeByMap(columnMap);
        log.info(">>>>>>>>下发修改：{}删除询价单信息结束>>>>>>>>>" , reinsDeleteDto.getCerTiNo());

        // 删除超赔信息表 begin
        log.info(">>>>>>>>下发修改：{}删除超赔信息表开始>>>>>>>>>" , reinsDeleteDto.getCerTiNo());
        List<FeoxLayer> feoxLayerList = iFeoxLayerService.listByMap(columnMap);
        String enquiryNo = "";
        if (ObjectUtil.isNotNull(feoxLayerList) && feoxLayerList.isEmpty()) {
            for(FeoxLayer feoxLayer : feoxLayerList){
                enquiryNo = feoxLayer.getEnquiryNo();
                break;
            }
            String finalEnquiryNo = enquiryNo;
            Map<String, Object> xColumnMap = new HashMap<String, Object>(16) {{
                put("ENQUIRYNO", finalEnquiryNo);
            }};
            iFeoxPlanService.removeByMap(xColumnMap);
            iFeoxReinsService.removeByMap(xColumnMap);
            iFeoxLayerService.removeByMap(xColumnMap);
        }
        log.info(">>>>>>>>下发修改：{}删除超赔信息表结束>>>>>>>>>" , reinsDeleteDto.getCerTiNo());
        // 删除试算表
        log.info(">>>>>>>>下发修改：{}删除试算信息开始>>>>>>>>>" , reinsDeleteDto.getCerTiNo());
        iPrppReinsShareService.removeByMap(columnMap);
        iPrppReinsTrialService.removeByMap(columnMap);
        log.info(">>>>>>>>下发修改：{}删除试算信息结束>>>>>>>>>" , reinsDeleteDto.getCerTiNo());

        // 删除危险单位
        log.info(">>>>>>>>下发修改：{}删除危险单位信息开始>>>>>>>>>" , reinsDeleteDto.getCerTiNo());
        iPrppDangerCoinsService.removeByMap(columnMap);
        iPrppDangerPlanService.removeByMap(columnMap);
        iPrppDangerTotService.removeByMap(columnMap);
        iPrppDangerItemService.removeByMap(columnMap);
        iPrppDangerUnitService.removeByMap(columnMap);
        log.info(">>>>>>>>下发修改：{}删除危险单位信息结束>>>>>>>>>" , reinsDeleteDto.getCerTiNo());
        // 删除临分分入确认表
        Map<String, Object> prpReinsColumnMap = new HashMap<String, Object>(16) {{
            put("CERTINO", reinsDeleteDto.getCerTiNo());
        }};
        iPrpReinsNotionService.removeByMap(prpReinsColumnMap);
        iPrpReinsVerifyService.removeByMap(prpReinsColumnMap);
        // 删除中间表数据
        iGeneratePrppApplyDangerUnitService.deleteReinsEndorInterf(reinsDeleteDto.getCerTiNo());
    }
}
